有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在java中实现不透明句柄

我想用java实现一个不透明句柄

也就是说,当用户对我的工厂类调用Create时,我创建了该类的一个对象,但不返回对象本身,而是返回一个表示该类实例的int。我将有一个HashMap,它将int存储为键,对象存储为值。 该类的其他每个方法都将int作为一个参数&;它将从HashMap中检索对象,并对相应的对象执行所需的操作。 将有一个remove方法将它从HashMap中删除,并允许对其进行垃圾收集

我想知道是否有任何现有的类/数据结构可以避免我必须实现代码的句柄部分

我认为我不能使用hashCodeidentityHashCode作为唯一标识符,因为它们不能保证是唯一的

如果我自己实现一个正在运行的计数器,我将不得不在创建唯一Id时处理线程安全问题,在从hashMap中删除对象时重用Id等问题。因此我想知道是否有任何现有类可以对此有所帮助


共 (4) 个答案

  1. # 1 楼答案

    以long值作为id。long值永远不会用完。重复使用int会导致更高的复杂性和速度减慢
    使用syncronized(或私有锁对象)编写get()set()和increment()很简单。否则使用AtomicLongincrementAndGet()

  2. # 2 楼答案

    我建议您使用基本的OO设计,它返回一个封装的对象——它简单、强大且众所周知

    不要从工厂返回int并将其传递给工厂方法。相反,为新创建的对象(抽象数据类型)声明一个特定的类,并返回这个ADT类的实例。将操作对象的方法从工厂移动到ADT类

    例如

    // file Widget.java
    package com.company.widgets;
    
    public class Widget {
        String widgetName;
        String widgetType;
        int widgetCode;
    
        // By making the constructor "protected", can stop arbitrary classes from 
        // constructing and ensure on the WidgetFactory can construct
        protected Widget(String widgetName,
                        String widgetType,
                        int widgetCode) {
             this.widgetName = widgetName;
             this.widgetType = widgetType;
             this.widgetCode = widgetCode;
        }
    
        public boolean equals(Object other) {
             ...
        }
    
        public int hashcode() {
             ...
        }
    
        public void widgetOperation1(String fred) {
            ...
        }
    
        public String widgetOperation2(int barney ) {
            ...
        }
    }
    
    //========================================================
    
    // file WidgetFactory.java
    package com.company.widgets;
    
    public class WidgetFactory {
        // Member attributes as needed. E.g. static Set of created Widget objects
        private static Set<Widget> widgetSet;
        static { widgetSet = new HashSet() }
    
        // 
        public static Widget createNewWidget() {
            Widget widget = new Widget();
            widgetSet.add(widget);
            return widget;
        }
    
        public static removeWidget(Widget widget) {
            widgetSet.remove(Widget)
        }
    }
    

    请注意,1000个对象并不多,因此此解决方案将非常有效。如果你真的需要优化每微秒的性能,你可以选择让工厂变得更智能,这样小部件就不会被删除,而是可以循环使用——例如,你可以有两套,widgetsInUseSet和widgetsRecycledSet

  3. # 3 楼答案

    让我们做简单的计算。你说过你最多有10000个对象,最多1小时的直播时间。让我们假设更严酷的条件——每1分钟10000个物体。32位整数将足够使用大约1年。此外,即使整数溢出,它也会再次从零开始,重用1年前使用的整数。在我看来,这已经足够了。所以,只需使用AtomicInteger,它运行速度非常快,足以满足您的需求

    如果你仍然有疑问,你可以有一个更具弹性的解决方案——当生成一个新句柄时,首先检查HashMap是否已经有这个键(这是一个非常快速的操作),如果确实有,只需选择下一个整数。它与操作系统中的https://superuser.com/questions/135007/how-are-pids-generated类似

  4. # 4 楼答案

    我会保留自己的柜台。如果担心线程安全,请使用AtomicInteger

    我也不会尝试重复使用ID:这将使调试和记录变得非常困难。 整数不太可能用完